#include "HkpRigidBodyCinfo.h"

namespace Havok
{
	namespace Dynamics
	{
		HkpRigidBodyCinfo::HkpRigidBodyCinfo(void)
		{
			m_info = new hkpRigidBodyCinfo();
		}

		void HkpRigidBodyCinfo::MotionType::set(HkpMotionType value)
		{
			m_info->m_motionType = (hkpMotion::MotionType)value;
		}

		HkpMotionType HkpRigidBodyCinfo::MotionType::get()
		{
			return (HkpMotionType)(hkpMotion::MotionType)m_info->m_motionType;
		}

		void HkpRigidBodyCinfo::Mass::set(float value)
		{
			m_info->m_mass = value;
		}

		float HkpRigidBodyCinfo::Mass::get()
		{
			return m_info->m_mass;
		}

		void HkpRigidBodyCinfo::Friction::set(float value)
		{
			m_info->m_friction = value;
		}

		float HkpRigidBodyCinfo::Friction::get()
		{
			return m_info->m_friction;
		}

		void HkpRigidBodyCinfo::Position::set(Vector3 value)
		{
			m_info->m_position.set(value.X, value.Y, value.Z);
		}

		Vector3 HkpRigidBodyCinfo::Position::get()
		{
			Vector3 v = Vector3::Zero;
			v.X = m_info->m_position.getSimdAt(0);
			v.Y = m_info->m_position.getSimdAt(1);
			v.Z = m_info->m_position.getSimdAt(2);
			return v;
		}

		void HkpRigidBodyCinfo::Shape::set(HkpShape^ value)
		{
			m_info->m_shape = value->m_shape;
		}

		void HkpRigidBodyCinfo::Rotation::set(Quaternion value)
		{
			m_info->m_rotation.set(value.X, value.Y, value.Z, value.W);
		}

		Quaternion HkpRigidBodyCinfo::Rotation::get()
		{
			const hkVector4* _w64 vec = &m_info->m_rotation.getImag();

			return Quaternion(vec->getSimdAt(0),vec->getSimdAt(1),vec->getSimdAt(2),m_info->m_rotation.getReal());
		}

		void HkpRigidBodyCinfo::LinearVelocity::set(Vector3 value)
		{
			m_info->m_linearVelocity.set(value.X, value.Y, value.Z);
		}

		Vector3 HkpRigidBodyCinfo::LinearVelocity::get()
		{
			return Vector3(
				m_info->m_linearVelocity.getSimdAt(0),
				m_info->m_linearVelocity.getSimdAt(1),
				m_info->m_linearVelocity.getSimdAt(2));
		}

		void HkpRigidBodyCinfo::AngularVelocity::set(Vector3 value)
		{
			m_info->m_angularVelocity.set(value.X, value.Y, value.Z);
		}

		Vector3 HkpRigidBodyCinfo::AngularVelocity::get()
		{
			return Vector3(
				m_info->m_angularVelocity.getSimdAt(0),
				m_info->m_angularVelocity.getSimdAt(1),
				m_info->m_angularVelocity.getSimdAt(2));
		}

		void HkpRigidBodyCinfo::LinearDamping::set(float value)
		{
			m_info->m_linearDamping = value;
		}

		float HkpRigidBodyCinfo::LinearDamping::get()
		{
			return m_info->m_linearDamping;
		}

		void HkpRigidBodyCinfo::AngularDamping::set(float value)
		{
			m_info->m_angularDamping = value;
		}

		float HkpRigidBodyCinfo::AngularDamping::get()
		{
			return m_info->m_angularDamping;
		}

		void HkpRigidBodyCinfo::Restitution::set(float value)
		{
			m_info->m_restitution = value;
		}

		float HkpRigidBodyCinfo::Restitution::get()
		{
			return m_info->m_restitution;
		}

		void HkpRigidBodyCinfo::AllowedPenetrationDepth::set(float value)
		{
			m_info->m_allowedPenetrationDepth = value;
		}

		float HkpRigidBodyCinfo::AllowedPenetrationDepth::get()
		{
			return m_info->m_allowedPenetrationDepth;
		}

		void HkpRigidBodyCinfo::QualityType::set(HkpCollidableQualityType value)
		{
			m_info->m_qualityType = (hkpCollidableQualityType)value;
		}

		HkpCollidableQualityType HkpRigidBodyCinfo::QualityType::get()
		{
			return (HkpCollidableQualityType)(hkpCollidableQualityType)m_info->m_qualityType;
		}

		void HkpRigidBodyCinfo::SolverDeactivation::set(HkpSolverDeactivation value)
		{
			m_info->m_solverDeactivation = (hkpRigidBodyCinfo::SolverDeactivation)value;
		}

		HkpSolverDeactivation HkpRigidBodyCinfo::SolverDeactivation::get()
		{
			return (HkpSolverDeactivation)(hkpRigidBodyCinfo::SolverDeactivation)m_info->m_solverDeactivation;
		}

		void HkpRigidBodyCinfo::CenterOfMass::set(Vector3 value)
		{
			m_info->m_centerOfMass.set(value.X, value.Y, value.Z);
		}

		Vector3 HkpRigidBodyCinfo::CenterOfMass::get()
		{
			return Vector3(
				m_info->m_centerOfMass.getSimdAt(0),
				m_info->m_centerOfMass.getSimdAt(1),
				m_info->m_centerOfMass.getSimdAt(2));
		}

		void HkpRigidBodyCinfo::MaxLinearVelocity::set(float value)
		{
			m_info->m_maxLinearVelocity = value;
		}

		float HkpRigidBodyCinfo::MaxLinearVelocity::get()
		{
			return m_info->m_maxLinearVelocity;
		}

		void HkpRigidBodyCinfo::MaxAngularVelocity::set(float value)
		{
			m_info->m_maxAngularVelocity = value;
		}

		float HkpRigidBodyCinfo::MaxAngularVelocity::get()
		{
			return m_info->m_maxAngularVelocity;
		}

		void HkpRigidBodyCinfo::AutoRemoveLevel::set(signed char value)
		{
			m_info->m_autoRemoveLevel = value;
		}

		signed char HkpRigidBodyCinfo::AutoRemoveLevel::get()
		{
			return m_info->m_autoRemoveLevel;
		}

		inline void calculateBoxInertiaTensor(hkpRigidBodyCinfo* m_info, float x, float y, float z, float mass)
		{
			hkpMassProperties m_massProperties;
			hkpInertiaTensorComputer::computeBoxVolumeMassProperties(hkVector4(x, y, z), mass, m_massProperties);
			m_info->m_inertiaTensor = m_massProperties.m_inertiaTensor;
		}

		void HkpRigidBodyCinfo::CalculateBoxInertiaTensor(Vector3 halfExtents, float mass)
		{
			calculateBoxInertiaTensor(m_info, halfExtents.X, halfExtents.Y, halfExtents.Z, m_info->m_mass);
		}

		inline void calculateSphereInertiaTensor(hkpRigidBodyCinfo* m_info, float radius, float mass)
		{
			hkpMassProperties m_massProperties;
			hkpInertiaTensorComputer::computeSphereVolumeMassProperties(radius, mass, m_massProperties);
			m_info->m_inertiaTensor = m_massProperties.m_inertiaTensor;
		}

		void HkpRigidBodyCinfo::CalculateSphereInertiaTensor(float radius, float mass)
		{
			calculateSphereInertiaTensor(m_info, radius, m_info->m_mass);
		}
	}
}
